package com.mingqijia.gassafety.shared.utils.commonUtils;

import cn.hutool.http.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gap.basic.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * @program: gassafety
 * @description: 获取地址对应的经纬度
 * @author: Mr.Wang
 * @create: 2022-09-19 17:06
 **/
@Slf4j
@Component
public class LocationUtil {
    private static final String baiDuUrlGeocoding =
            "https://api.map.baidu.com/geocoding/v3/?address=%s&ak=%s&output=%s";

    @Value("${baidu.maps.key}")
    private String baiDuMapsKey;

    private static final String baiDuGeocoding =
            "https://api.map.baidu.com/reverse_geocoding/v3/?location=%s,%s&coordtype=bd09ll&ak=%s&output=%s";

    private static final String baiduUrlDistrict =
            "https://api.map.baidu.com/api_region_search/v1/?keyword=%s&sub_admin=%s&ak=%s&extensions_code=1&output=%s";

    /**
     * 获取百度行政区信息
     * @param adCode
     * @param subAdmin
     * @return
     */
    public JSONObject getBaiduRegion(String adCode,String subAdmin){
        HttpRequest httpRequest = HttpUtil.createRequest(
                Method.GET,
                String.format(baiduUrlDistrict, adCode, subAdmin, baiDuMapsKey, "json"));
        HttpResponse httpResponse = httpRequest.execute();
        JSONObject resultJson = JSON.parseObject(httpResponse.body());
        if (!Objects.equals(httpResponse.getStatus(), HttpStatus.HTTP_OK)) {
            throw new BizException("调用百度地图 行政区查询 接口查询异常:" + resultJson.toJSONString());
        }
        log.info("获取行政区查询, url:{}, 结果: {}", httpRequest.getUrl(), resultJson.toJSONString());
        return resultJson;
    }

    /**
     * 根据经纬度获取市，区，街道编码名称
     * @param lat
     * @param lng
     * @return
     */
    public JSONObject baiDuGeocoding(Double lat,Double lng){
        HttpRequest httpRequest = HttpUtil.createRequest(
                Method.GET,
                String.format(baiDuGeocoding, lat, lng, baiDuMapsKey, "json"));
        HttpResponse httpResponse = httpRequest.execute();
        JSONObject resultJson = JSON.parseObject(httpResponse.body());
        if (!Objects.equals(httpResponse.getStatus(), HttpStatus.HTTP_OK)) {
            throw new BizException("调用百度地图 经纬度 接口异常:" + resultJson.toJSONString());
        }
        log.info("获取地址对应经纬度, url:{}, 结果: {}", httpRequest.getUrl(), resultJson.toJSONString());
        return resultJson;
    }

    /**
     * 根据地址获取经纬度
     * @param address
     * @return
     */
    public double[] baiDuUrlGeocoding(String address){
        //获取经纬度
        HttpRequest httpRequest = HttpUtil.createRequest(Method.GET, String.format(baiDuUrlGeocoding, address, baiDuMapsKey, "json"));
        HttpResponse httpResponse = httpRequest.execute();
        JSONObject resultJson = JSON.parseObject(httpResponse.body());
        if (!Objects.equals(httpResponse.getStatus(), HttpStatus.HTTP_OK)) {
            throw new BizException("调用百度地图 经纬度 接口异常:" + resultJson.toJSONString());
        }
        double positionLat=0;
        double positionLon=0;
        log.info("获取地址对应经纬度, url:{}, 结果: {}", httpRequest.getUrl(), resultJson.toJSONString());
        if ("0".equals(resultJson.getString("status")) &&
                null != resultJson.getJSONObject("result") &&
                null != resultJson.getJSONObject("result").getJSONObject("location")) {
            JSONObject locationObject = resultJson.getJSONObject("result").getJSONObject("location");
            //维度
            Double lat = locationObject.getDouble("lat");
            //经度
            Double lng = locationObject.getDouble("lng");
            positionLat = new BigDecimal(lat).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
            positionLon = new BigDecimal(lng).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
            return new double[]{positionLat, positionLon};
        }
        return new double[]{positionLat, positionLon};
    }
}
